Component org.nuxeo.ecm.directory.ldap.LDAPDirectoryFactory
In bundle org.nuxeo.ecm.directory.ldap
Documentation
The LDAPDirectoryFactory component provides implementation of the Directory API using an external LDAP server as storage backend, typically to fetch users and groups data check password based authentication.
Requirements
Resolution Order
810
The resolution order represents the order in which this component has been resolved by the Nuxeo Runtime
framework.
You can influence this order by adding "require" tags in your component declaration, to make sure it is resolved after another component.
Start Order
845
The start order represents the order in which this component has been started by the Nuxeo Runtime framework.
This number is interesting to tweak if your Java component interacts with other components, and needs to be started before or after another one.
It can be changed by implementing the method "Component#getApplicationStartedOrder()" on your Java component: components are sorted according to this reference value, in increasing order.
The default value is 1000, and the repository initialization uses number 100. Negative values can also be used.
Implementation
Class:
org.nuxeo.ecm.directory.ldap.LDAPDirectoryFactory
Services
Extension Points
XML Source
<?xml version='1.0' encoding='UTF-8'?>
<component name="org.nuxeo.ecm.directory.ldap.LDAPDirectoryFactory">
<require>org.nuxeo.ecm.directory.DirectoryServiceImpl</require>
<documentation>
The LDAPDirectoryFactory component provides implementation of the
Directory API using an external LDAP server as storage backend,
typically to fetch users and groups data check password based
authentication.
@author Olivier Grisel (ogrisel@nuxeo.com)
</documentation>
<implementation class="org.nuxeo.ecm.directory.ldap.LDAPDirectoryFactory"/>
<service>
<provide interface="org.nuxeo.ecm.directory.ldap.LDAPDirectoryFactory"/>
</service>
<extension-point name="servers">
<documentation>
The servers extension point is used to register network connection
parameters to a pool of LDAP servers.
Examples:
<code>
<server name="default">
<ldapUrl>ldap://localhost:389</ldapUrl>
<ldapUrl>ldap://server2:389</ldapUrl>
<ldapUrl>ldaps://server3:389</ldapUrl>
<!-- LDAP SRV DNS resolution on _ldap._tcp.example.com -->
<ldapUrl>ldap:///dc=example,dc=com</ldapUrl>
<!-- LDAP SRV DNS resolution on _gc._tcp.example.com -->
<ldapUrl srvPrefix="_gc._tcp">ldap:///dc=example,dc=com</ldapUrl>
<connectionTimeout>10000</connectionTimeout>
<retries>5</retries>
<poolingEnabled>true</poolingEnabled>
<poolingConnectionTimeout>60000</poolingConnectionTimeout>
<verifyServerCert>true</verifyServerCert>
<bindDn>cn=nuxeo5,ou=applications,dc=example,dc=com</bindDn>
<bindPassword>********</bindPassword>
</server>
</code>
The ldapUrl tags point to server (IP address or DNS name) and
ports. If more than one is provided, the Nuxeo EP will use a pool
of load balanced connections to each server. They are assumed to
be replicated versions of a master server that should belong to
the list.
The connectionTimeout element specifies a connection timeout in milliseconds.
The default is 10000.
The retries element indicates how many times the request will be retried
if LDAP server returns a ServiceUnavailableException. The default is 5.
The poolingEnabled element specifies whether to use LDAP connection pooling.
The default is true.
The poolingTimeout element specifies, in milliseconds, how long a connection
may remain in the pool when LDAP connection pooling is enabled.
The default is 60000.
The verifyServerCert element specifies whether, in SSL mode, all certificates
should be checked. This should only be disabled when testing with test server
having self-signed certificates. The default is true.
The bindDn and bindPassword credentials are used by Nuxeo EP to
access the content of the LDAP servers. It should have the read
permission to any entry that is to be used by Nuxeo EP and write
right to branches were Nuxeo EP is supposed to create or edit
entries.
For instance, in OpenLDAP you should have ACLs such as:
<code>
access to attrs="userPassword"
by dn="cn=ldapadmin,dc=example,dc=com" write
by dn="cn=nuxeo5,ou=applications,dc=example,dc=com" write
by anonymous auth
by self write
by * none
access to dn.base="" by * read
# nuxeo5 can manage the ou=people branch
access to dn.subtree="ou=people,dc=example,dc=com"
by dn="cn=nuxeo5,ou=applications,dc=example,dc=com" write
by users read
by self write
by * none
access to dn.subtree="ou=groups,dc=example,dc=com"
by dn="cn=nuxeo5,ou=applications,dc=example,dc=com" write
by users read
by self write
by * none
# The admin dn has full write access
# other
access to *
by dn="cn=ldapadmin,dc=example,dc=com" write
by users read
by * none
</code>
User authentication is done using a bind method against the user
provided login and password from the login form and not the bindDn
/ bindPassword credentials.
</documentation>
<object class="org.nuxeo.ecm.directory.ldap.LDAPServerDescriptor"/>
</extension-point>
<extension-point name="directories">
<documentation>
The directories extension point is used to register LDAP filtering
parameters to identify which part of the LDAP branches are actually
used by Nuxeo EP to fetch its entries.
Examples:
<code>
<directory name="userDirectory">
<server>default</server>
<schema>user</schema>
<types>
<type>system</type>
</types>
<idField>username</idField>
<idCase>unchanged</idCase>
<passwordField>password</passwordField>
<passwordHashAlgorithm>SSHA</passwordHashAlgorithm>
<searchBaseDn>ou=people,dc=example,dc=com</searchBaseDn>
<searchClass>person</searchClass>
<searchFilter>(&(sn=toto*)(myCustomAttribute=somevalue))</searchFilter>
<searchScope>onelevel</searchScope>
<readOnly>false</readOnly>
<cacheTimeout>3600</cacheTimeout>
<cacheMaxSize>1000</cacheMaxSize>
<creationBaseDn>ou=people,dc=example,dc=com</creationBaseDn>
<creationClass>top</creationClass>
<creationClass>person</creationClass>
<creationClass>organizationalPerson</creationClass>
<creationClass>inetOrgPerson</creationClass>
<rdnAttribute>uid</rdnAttribute>
<querySizeLimit>200</querySizeLimit>
<queryTimeLimit>0</queryTimeLimit>
<fieldMapping name="username">uid</fieldMapping>
<fieldMapping name="password">********</fieldMapping>
<fieldMapping name="firstName">givenName</fieldMapping>
<fieldMapping name="lastName">sn</fieldMapping>
<fieldMapping name="company">o</fieldMapping>
<fieldMapping name="email">mail</fieldMapping>
<references>
<inverseReference field="groups" directory="groupDirectory" dualReferenceField="members"/>
</references>
</directory>
<directory name="groupDirectory">
<server>default</server>
<schema>group</schema>
<idField>groupname</idField>
<searchBaseDn>ou=groups,dc=example,dc=com</searchBaseDn>
<searchFilter>(|(objectClass=groupOfUniqueNames)(objectClass=groupOfURLs))</searchFilter>
<searchScope>subtree</searchScope>
<!-- Special entry adaptor that makes entries in the ou=editable branch editable
other entries have the readonly flag. This require adding a "dn" xs:string field
to the group schema.
-->
<entryAdaptor class="org.nuxeo.ecm.directory.impl.WritePolicyEntryAdaptor">
<parameter name="fieldName">dn</parameter>
<parameter name="regexp">.*,ou=editable,ou=groups,dc=example,dc=com</parameter>
</entryAdaptor>
<readOnly>false</readOnly>
<cacheTimeout>3600</cacheTimeout>
<cacheMaxSize>1000</cacheMaxSize>
<creationBaseDn>ou=editable,ou=groups,dc=example,dc=com</creationBaseDn>
<creationClass>top</creationClass>
<creationClass>groupOfUniqueNames</creationClass>
<rdnAttribute>cn</rdnAttribute>
<querySizeLimit>200</querySizeLimit>
<queryTimeLimit>0</queryTimeLimit>
<fieldMapping name="groupname">cn</fieldMapping>
<references>
<!-- LDAP reference resolve DNs embedded in uniqueMember attributes
If the target directory has no specific filtering policy, it is most
of the time not necessary to enable the 'forceDnConsistencyCheck' policy.
Enabling this option will fetch each reference entry to ensure its
existence in the target directory.
-->
<ldapReference field="members" directory="userDirectory" forceDnConsistencyCheck="false" staticAttributeIdIsDn="true" staticAttributeId="uniqueMember" dynamicAttributeId="memberURL"/>
<ldapReference field="subGroups" directory="groupDirectory" forceDnConsistencyCheck="false" staticAttributeId="uniqueMember" dynamicAttributeId="memberURL"/>
<inverseReference field="parentGroups" directory="groupDirectory" dualReferenceField="subGroups"/>
<ldapTreeReference field="children" directory="groupDirectory" scope="onelevel"/>
<inverseReference field="parents" directory="groupDirectory" dualReferenceField="children"/>
</references>
</directory>
</code>
In the previous examples we configured two directories one for the
users and one for the groups of users. Each directory uses a
single schema which is to be registered as any core document
schema and that will be used to build a DocumentModel for each
matching entry of the directory.
Nuxeo EP provides group resolution for statically dn-referenced
entries (in read and write mode) and for dynamically ldapUrl
matched entries (readonly). You may also need to statically
reference entries without a dn using the 'staticAttributeIdIsDn'
attribute.
The references tags are used to dynamically build nxs:stringList
fields of that schema that are to compute membership relationships
between users and groups or between parent groups and sub groups.
It can also resole children and parents following the ldap tree
structure.
You have two ways for declaring a dynamic reference in a 'references' tag.
You can use 'dynamicAttributeId' to point to an ldap attribute that
contains an ldap url.
<code>
<ldapReference field="members" directory="userDirectory" dynamicAttributeId="memberURL"/>
</code>
Or, you can use a subtag 'dynamicReference' to declare attributes that
contain a DN, a filter and a type. This values will be used to selected
the references.
<code>
<ldapReference field="members" directory="userDirectory"/>
<dynamicReference filter="ldapAttribute" type="subtree/onelevel" baseDN="ldapAttribute"/>
<ldapReference/>
</code>
When using dynamic references, caching is advised since dynamic group
resolution can be expensive.
The element "idCase" makes it possible to control the case of the
identifier on Nuxeo side. It accepts values "upper", "lower" or
"unchanged". It is useful when changing case on the LDAP without affecting
Nuxeo (for rights management for instance which is case sensitive for
instance).
Dependening on your LDAP Backend implementation, if you have some specific restriction
(for example on password, or logins ...), you may want Nuxeo to handle the validation
errors of your server on the Nuxeo side.
Since there error code and message may vary depending on the LDAP server provider, you
may need to provide a custom class that knows how to handle the Exceptions returned by it.
For this you can specify a class that will be in charge of this task.
<code>
<ldapExceptionHandler>org.nuxeo.ecm.directory.ldap.DefaultLdapExceptionProcessor</ldapExceptionHandler>
</code>
This class should implement org.nuxeo.ecm.directory.ldap.LdapExceptionProcessor and return
a RecoverableClientException for any exception that should be displayed to the user.
By default, referrals will be automatically resolved, if you don't want that behavior (since 5.9.4) you can use the followReferrals tag
<code>
<directory name="groupDirectory">
....
<followReferrals>false</followReferrals>
...
</directory>
</code>
</documentation>
<object class="org.nuxeo.ecm.directory.ldap.LDAPDirectoryDescriptor"/>
</extension-point>
</component>